package com.gitee.ec.common;

import com.gitee.ec.EverythingClient;
import com.gitee.ec.kernel.EverythingClientV4;
import com.gitee.ec.kernel.FileTime;
import com.sun.jna.WString;

import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author hongda.li
 */
public final class EverythingUtils {
    /**
     * 客户端实例
     */
    private static final EverythingClient CLIENT = new EverythingClientV4();

    private EverythingUtils() {
    }

    /**
     * 获取客户端实例
     *
     * @return 客户端实例
     */
    public static EverythingClient getClient() {
        return CLIENT;
    }

    public static <T> T filterOutput(List<OutputItemName> range,
                                     OutputItemName current,
                                     Supplier<T> supplier) {
        if (range.contains(current)) {
            return supplier.get();
        } else {
            return null;
        }
    }

    public static void filterOutput(List<OutputItemName> range,
                                    OutputItemName current,
                                    Runnable runnable) {
        if (range.contains(current)) {
            runnable.run();
        }
    }

    public static String readString(WString string) {
        return string == null ? null : string.toString();
    }

    public static String readString(CharBuffer buffer) {
        StringBuilder builder = new StringBuilder();
        while (buffer.hasRemaining()) {
            char ch = buffer.get();
            if (ch != '\0') {
                builder.append(ch);
            }
        }
        return builder.length() == 0 ? null : builder.toString();
    }

    public static Integer readInt(IntBuffer buffer) {
        if (buffer.hasRemaining()) {
            return buffer.get();
        } else {
            return null;
        }
    }

    public static Double readDouble(IntBuffer buffer) {
        return Optional.ofNullable(EverythingUtils.readInt(buffer))
                .map(Double::valueOf)
                .orElse(null);
    }

    public static Date readDate(FileTime time) {
        return time.dwLowDateTime == 0 && time.dwHighDateTime == 0
                ? null
                : time.toDate();
    }
}
